package cn.cocho.android.mc.comp.image;

import android.content.Context;
import android.graphics.Bitmap;
import android.graphics.Canvas;
import android.graphics.Matrix;
import android.graphics.PointF;
import android.util.AttributeSet;
import android.util.FloatMath;
import android.view.Display;
import android.view.MotionEvent;
import android.widget.ImageView;

public class ZoomImageView extends ImageView {

	Matrix matrix = new Matrix();
	Matrix actionMatrix = new Matrix();
	Matrix savedMatrix = new Matrix();
	private boolean matrixCheck = false;

	private int mode = NONE;
	private static final int NONE = 0;
	private static final int DRAG = 1;
	private static final int ZOOM = 2;

	private int screenWidth = 0;
	private int screenHeight = 0;
	private int zoomInScale = 1;
	private int zoomOutScale = 1;

	private Bitmap imageBtm = null;
	private int btmWidth = 0;
	private int btmHeight = 0;

	PointF start = new PointF();
	PointF mid = new PointF();
	int x_down = 0;
	int y_down = 0;
	float oldDist = 1f;
	float oldRotation = 0;

	public ZoomImageView(Context context) {
		super(context);
		init();
	}

	public ZoomImageView(Context context, AttributeSet attrs) {
		super(context, attrs);
		// TODO Auto-generated constructor stub
		init();
	}

	private void init() {
		matrix = new Matrix();
	}

	protected void onDraw(Canvas canvas) {
		if (imageBtm == null) {
			super.onDraw(canvas);
			return;
		}
		canvas.save();
		canvas.drawBitmap(imageBtm, matrix, null);
		canvas.restore();
	}

	private float[] getMatrixValues(Matrix matrix) {// 由于用float类型进行预算很消耗性能，故转化为int
		float[] values = new float[9];
		matrix.getValues(values);

		return values;
	}

	/**
	 * 获取当前显示图片的宽度
	 * 
	 * @return
	 * @author yzl
	 * @time 2013-5-24下午3:52:17
	 */
	private double getCurWidth() {
		float[] values = getMatrixValues(actionMatrix);
		int xWidthDif = (int) (values[0] * btmWidth);
		int yWidthDif = (int) (values[3] * btmWidth);
		double width = Math.sqrt(xWidthDif * xWidthDif + yWidthDif * yWidthDif);

		return width;
	}

	/**
	 * 缩放比率判断
	 * 
	 * @return
	 * @author yzl
	 * @time 2013-5-24下午3:51:54
	 */
	private boolean scaleLimit() {
		double width = getCurWidth();
		if (width < zoomOutScale || width > zoomInScale) {
			return true;
		}
		return false;
	}

	/**
	 * 触碰两点间距离
	 * 
	 * @param event
	 * @return
	 * @author yzl
	 * @time 2013-5-24下午3:51:37
	 */
	private float spacing(MotionEvent event) {
		float x = event.getX(0) - event.getX(1);
		float y = event.getY(0) - event.getY(1);
		return FloatMath.sqrt(x * x + y * y);
	}

	/**
	 * 取手势中心点
	 * 
	 * @param point
	 * @param event
	 * @author yzl
	 * @time 2013-5-24下午3:51:29
	 */
	private void midPoint(PointF point, MotionEvent event) {
		float x = event.getX(0) + event.getX(1);
		float y = event.getY(0) + event.getY(1);
		point.set(x / 2, y / 2);
	}

	private void down(MotionEvent event) {
		mode = DRAG;
		x_down = (int) event.getX();
		y_down = (int) event.getY();
		savedMatrix.set(matrix);
	}

	private void move(MotionEvent event) {
		if (mode == ZOOM) {
			zoom(event);
		} else if (mode == DRAG) {
			drag(event);
		}
	}

	private void pointerDown(MotionEvent event) {
		mode = ZOOM;
		oldDist = spacing(event);
		savedMatrix.set(matrix);
		midPoint(mid, event);
	}

	private void zoom(MotionEvent event) {
		actionMatrix.set(savedMatrix);
		float newDist = spacing(event);
		float scale = newDist / oldDist;
		actionMatrix.postScale(scale, scale, mid.x, mid.y);// 縮放
		matrixCheck = scaleLimit();
		if (matrixCheck == false) {
			matrix.set(actionMatrix);
			invalidate();
		}
	}

	private void drag(MotionEvent event) {
		actionMatrix.set(savedMatrix);
		actionMatrix.postTranslate(event.getX() - x_down, event.getY() - y_down);// 平移
		matrix.set(actionMatrix);
		invalidate();
	}

	public boolean onTouchEvent(MotionEvent event) {
		if (imageBtm == null) {
			return false;
		}
		switch (event.getAction() & MotionEvent.ACTION_MASK) {
		case MotionEvent.ACTION_DOWN:
			down(event);
			break;
		case MotionEvent.ACTION_POINTER_DOWN:
			pointerDown(event);
			break;
		case MotionEvent.ACTION_MOVE:
			move(event);
			break;
		case MotionEvent.ACTION_UP:
		case MotionEvent.ACTION_POINTER_UP:
			mode = NONE;
			break;
		}
		return true;
	}

	/**
	 * 设置缩放图片，及屏幕Display。注：bitmap图片的宽度必须>=200
	 * 
	 * @param imageBtm
	 * @param dispaly
	 * @author yzl
	 * @time 2013-5-23上午10:34:26
	 */
	public void setImageBtm(Bitmap imageBtm, Display display) {
		this.imageBtm = imageBtm;
		btmWidth = imageBtm.getWidth();
		btmHeight = imageBtm.getHeight();
		screenWidth = display.getWidth();
		screenHeight = display.getHeight();
		zoomInScale = screenWidth * 3;
		zoomOutScale = screenWidth / 5;
		layoutToCenter();
	}

	/**
	 * 设置图片显示居中
	 * 
	 * @author yzl
	 * @time 2013-5-24下午3:50:54
	 */
	public void layoutToCenter() {
		int tran_width = 0;
		int tran_height = 0;
		int fill_width = screenWidth - btmWidth;
		int fill_height = screenHeight - btmHeight;

		if (fill_width <= 0 && fill_height <= 0) {
			return;
		}
		tran_width = fill_width / 2;
		tran_height = fill_height / 2;
		actionMatrix.postTranslate(tran_width, tran_height);// 平移
		matrix.set(actionMatrix);
		invalidate();
	}
}
